package utils

import (
	"errors"

	"github.com/zeromicro/go-zero/core/logx"
	"gorm.io/gorm"
)

const (
	DB_CACHE_PREFIX = "db:"
)

func GetData(target any) bool {
	result := Db.Where(target).First(target)
	if result.Error != nil {
		logx.Errorf("GetData is error:%s", result.Error)
		return false
	}
	return true
}

func GetDataById(id uint, target any) bool {
	err := Db.First(target, id)
	if err != nil {
		return false
	}
	return true
}

func GetDataWhere(target any, where map[string]any, order string) bool {
	result := Db.Where(where).Order(order).First(target)
	if result.Error != nil {
		if !errors.Is(result.Error, gorm.ErrRecordNotFound) {
			logx.Error("GetDataWhere is error:", result.Error)
		}
		return false
	}
	return true
}

func FindDatas(target any, where map[string]any, order string) int64 {
	result := Db.Where(where).Order(order).Find(target)
	if result.Error != nil {
		logx.Error("FindDatas is error:", result.Error)
	}
	return result.RowsAffected
}

func TxCount(tx *gorm.DB) int64 {
	var total int64
	result := tx.Debug().Count(&total)
	if result.Error != nil {
		logx.Error("TxCount is error:", result.Error)
		return 0
	}
	return total
}

func TxPage(tx *gorm.DB, page int, target any) error {
	return TxPageSize(tx, page, 20, target)
}

func TxPageSize(tx *gorm.DB, page int, pageSize int, target any) error {
	offset := (page - 1) * pageSize
	result := tx.Debug().Offset(offset).Limit(pageSize).Find(target)
	if result.Error != nil {
		logx.Error("TxCount is error:", result.Error)
		return result.Error
	}
	return nil
}

func FindPageWhere(target any, where map[string]any, page int, order string) int64 {
	pageSize := 20
	return FindPageSizeWhere(target, where, page, pageSize, order)
}

func FindPageSizeWhere(target any, where map[string]any, page int, pageSize int, order string) int64 {
	if page < 1 {
		page = 1
	}
	offset := (page - 1) * pageSize
	result := Db.Where(where).Offset(offset).Limit(pageSize).Order(order).Find(target)
	if result.Error != nil {
		if !errors.Is(result.Error, gorm.ErrRecordNotFound) {
			logx.Error("FindPageSizeWhere is error:", result.Error)
		}
	}
	return result.RowsAffected
}

func CountDataWhere(target any, where map[string]any) int64 {
	var total int64
	Db.Where(where).Count(&total)
	return total
}

// 使用map 更新map的所有列，使用struct会忽略零值
func UpdateById(id uint, data any) error {
	result := Db.Where("id = ?", id).Save(data)
	if result.Error != nil {
		logx.Error("UpdateById is error:", result.Error)
	}
	// 删除缓存
	return result.Error
}

// 使用map 更新map的所有列，使用struct会忽略零值
func UpdateByIdCols(id uint, data any, cols string) error {
	result := Db.Where("id = ?", id).Select(cols).Updates(data)
	if result.Error != nil {
		logx.Error("UpdateByIdCols is error:", result.Error)
	}
	return result.Error
}

// 使用map 更新map的所有列，使用struct会忽略零值
func Update(target any, where map[string]any) error {
	result := Db.Where(where).Updates(target)
	if result.Error != nil {
		logx.Error("Update is error:", result.Error)
	}
	return result.Error
}

// 使用map 更新map的所有列，使用struct会忽略零值
func UpdateCols(target map[string]any, where map[string]any) error {
	result := Db.Where(where).Updates(target)
	if result.Error != nil {
		logx.Error("UpdateMustCols is error:", result.Error)
	}
	return result.Error
}

func InsertData(data any) error {
	result := Db.Debug().Create(data)
	if result.Error != nil {
		logx.Error("InsertData is error:", result.Error)
	}
	return result.Error
}

func DeleteData(target any, where map[string]any) error {
	result := Db.Where(where).Delete(target)
	if result.Error != nil {
		logx.Error("DeleteData is error:", result.Error)
	}
	return result.Error
}

func DeleteDataById(id uint, target any) error {
	result := Db.Delete(target, id)
	if result.Error != nil {
		logx.Error("DeleteDataById is error:", result.Error)
	}
	return result.Error
}
